import React, { useState, useEffect } from 'react';
import {
  Card,
  Table,
  Button,
  Space,
  Modal,
  Form,
  Input,
  Select,
  message,
  Tag,
  Popconfirm,
  Drawer,
  Typography,
  Spin,
} from 'antd';
import {
  PlusOutlined,
  EditOutlined,
  DeleteOutlined,
  PlayCircleOutlined,
  EyeOutlined,
  CodeOutlined,
  HistoryOutlined,
} from '@ant-design/icons';
import type { ColumnsType } from 'antd/es/table';
import { scriptApi } from '@/services/api';
import type { Script, ScriptExecution, ScriptParameter } from '@/types';
import ScriptEditor from './ScriptEditor';
import ExecutionResult from './ExecutionResult';
import { history } from 'umi';

const { TextArea } = Input;
const { Option } = Select;
const { Text, Paragraph } = Typography;

const Scripts: React.FC = () => {
  const [scripts, setScripts] = useState<Script[]>([]);
  const [loading, setLoading] = useState(false);
  const [total, setTotal] = useState(0);
  const [current, setCurrent] = useState(1);
  const [pageSize, setPageSize] = useState(10);
  
  const [editModalVisible, setEditModalVisible] = useState(false);
  const [editorVisible, setEditorVisible] = useState(false);
  const [executionDrawerVisible, setExecutionDrawerVisible] = useState(false);
  
  const [currentScript, setCurrentScript] = useState<Script | null>(null);
  const [currentExecution, setCurrentExecution] = useState<ScriptExecution | null>(null);
  const [scriptParameters, setScriptParameters] = useState<ScriptParameter[]>([]);
  const [parameterValues, setParameterValues] = useState<Record<string, string>>({});
  
  const [form] = Form.useForm();
  const [executeForm] = Form.useForm();
  
  const [filters, setFilters] = useState<{
    name?: string;
    type?: 'node' | 'python' | 'bash';
    status?: string;
  }>({});

  const fetchScripts = async () => {
    setLoading(true);
    try {
      const response = await scriptApi.getScripts({
        page: current,
        pageSize,
        ...filters,
      });
      setScripts(response.data?.data || []);
      setTotal(response.data?.total || 0);
    } catch (error) {
      message.error('获取脚本列表失败');
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    fetchScripts();
  }, [current, pageSize, filters]);

  const handleCreate = () => {
    setCurrentScript(null);
    form.resetFields();
    setEditModalVisible(true);
  };

  const handleEdit = (record: Script) => {
    setCurrentScript(record);
    form.setFieldsValue(record);
    setEditModalVisible(true);
  };

  const handleSave = async (values: any) => {
    try {
      // 前端基本安全检查
      if (values.content) {
        const dangerousPatterns = [
          /rm\s+-rf?\s+/gi,
          /os\.system/gi,
          /subprocess\.(?:call|run|Popen)/gi,
          /child_process\.(?:exec|spawn)/gi,
          /eval\s*\(/gi,
        ];
        
        for (const pattern of dangerousPatterns) {
          if (pattern.test(values.content)) {
            message.warning('脚本内容可能包含危险操作，请检查后重试');
            return;
          }
        }
      }

      if (currentScript) {
        await scriptApi.updateScript(currentScript.id, values);
        message.success('更新脚本成功');
      } else {
        await scriptApi.createScript(values);
        message.success('创建脚本成功');
      }
      setEditModalVisible(false);
      fetchScripts();
    } catch (error: any) {
      const errorMessage = error.response?.data?.message || (currentScript ? '更新脚本失败' : '创建脚本失败');
      message.error(errorMessage);
    }
  };

  const handleDelete = async (id: number) => {
    try {
      await scriptApi.deleteScript(id);
      message.success('删除脚本成功');
      fetchScripts();
    } catch (error) {
      message.error('删除脚本失败');
    }
  };

  const handleExecute = async (script: Script) => {
    setCurrentScript(script);
    executeForm.resetFields();
    
    try {
      // 获取脚本参数
      const paramResponse = await scriptApi.getScriptParameters(script.id);
      const parameters = paramResponse.data || [];
      setScriptParameters(parameters);
      
      // 初始化参数默认值
      const defaultValues: Record<string, string> = {};
      parameters.forEach(param => {
        defaultValues[param.name] = param.defaultValue;
      });
      setParameterValues(defaultValues);
      
      Modal.confirm({
        title: `执行脚本: ${script.name}`,
        width: 800,
        content: (
          <div>
            <p style={{ color: '#666', marginBottom: 16 }}>
              警告：脚本将在服务器上执行，请确保脚本内容安全可靠。
            </p>
            <Form form={executeForm} layout="vertical">
              {parameters.length > 0 && (
                <Form.Item label="脚本参数">
                  <Table
                    size="small"
                    dataSource={parameters}
                    pagination={false}
                    columns={[
                      {
                        title: '参数名',
                        dataIndex: 'name',
                        key: 'name',
                        width: 120,
                      },
                      {
                        title: '描述',
                        dataIndex: 'description',
                        key: 'description',
                        width: 150,
                      },
                      {
                        title: '参数值',
                        key: 'value',
                        render: (_, record) => (
                          <Input
                            placeholder={`默认: ${record.defaultValue}`}
                            defaultValue={record.defaultValue}
                            onChange={(e) => {
                              setParameterValues(prev => ({
                                ...prev,
                                [record.name]: e.target.value
                              }));
                            }}
                            maxLength={1000}
                          />
                        ),
                      },
                    ]}
                    rowKey="name"
                  />
                </Form.Item>
              )}
              <Form.Item 
                label="额外参数" 
                name="args"
                rules={[
                  {
                    validator: (_, value) => {
                      if (value) {
                        // 检查危险字符
                        if (/[;&|`$()]/.test(value)) {
                          return Promise.reject(new Error('参数不能包含特殊字符 ; & | ` $ ( )'));
                        }
                        if (value.includes('../')) {
                          return Promise.reject(new Error('参数不能包含路径遍历字符'));
                        }
                        if (value.length > 1000) {
                          return Promise.reject(new Error('参数长度不能超过1000个字符'));
                        }
                      }
                      return Promise.resolve();
                    },
                  },
                ]}
              >
                <Input 
                  placeholder="输入额外执行参数（可选）"
                  maxLength={1000}
                  showCount
                />
              </Form.Item>
            </Form>
          </div>
        ),
        onOk: async () => {
          try {
            await executeForm.validateFields();
            const values = executeForm.getFieldsValue();
            const executeData = {
              args: values.args,
              parameters: parameterValues
            };
            const response = await scriptApi.executeScript(script.id, executeData);
            console.log('[DEBUG] executeScript API response:', response);
            const execution = response.data;
            console.log('[DEBUG] extracted execution:', execution);
            message.success('脚本执行已启动');
            setCurrentExecution(execution);
            setExecutionDrawerVisible(true);
          } catch (error: any) {
            if (error.errorFields) {
              // 表单验证错误
              return Promise.reject();
            }
            const errorMessage = error.response?.data?.message || '执行脚本失败';
            message.error(errorMessage);
          }
        },
      });
    } catch (error: any) {
      console.error('获取脚本参数失败:', error);
      // 如果获取参数失败，仍然可以执行脚本，但没有参数表格
      Modal.confirm({
        title: `执行脚本: ${script.name}`,
        content: (
          <div>
            <p style={{ color: '#666', marginBottom: 16 }}>
              警告：脚本将在服务器上执行，请确保脚本内容安全可靠。
            </p>
            <Form form={executeForm} layout="vertical">
              <Form.Item 
                label="参数" 
                name="args"
                rules={[
                  {
                    validator: (_, value) => {
                      if (value) {
                        // 检查危险字符
                        if (/[;&|`$()]/.test(value)) {
                          return Promise.reject(new Error('参数不能包含特殊字符 ; & | ` $ ( )'));
                        }
                        if (value.includes('../')) {
                          return Promise.reject(new Error('参数不能包含路径遍历字符'));
                        }
                        if (value.length > 1000) {
                          return Promise.reject(new Error('参数长度不能超过1000个字符'));
                        }
                      }
                      return Promise.resolve();
                    },
                  },
                ]}
              >
                <Input 
                  placeholder="输入执行参数（可选）"
                  maxLength={1000}
                  showCount
                />
              </Form.Item>
            </Form>
          </div>
        ),
        onOk: async () => {
          try {
            await executeForm.validateFields();
            const values = executeForm.getFieldsValue();
            const response = await scriptApi.executeScript(script.id, values);
            console.log('[DEBUG] executeScript API response:', response);
            const execution = response.data;
            console.log('[DEBUG] extracted execution:', execution);
            message.success('脚本执行已启动');
            setCurrentExecution(execution);
            setExecutionDrawerVisible(true);
          } catch (error: any) {
            if (error.errorFields) {
              // 表单验证错误
              return Promise.reject();
            }
            const errorMessage = error.response?.data?.message || '执行脚本失败';
            message.error(errorMessage);
          }
        },
      });
    }
  };

  const handleViewCode = (script: Script) => {
    setCurrentScript(script);
    setEditorVisible(true);
  };

  const handleViewHistory = (script: Script) => {
    history.push(`/business/scripts/${script.id}/history`);
  };

  const getStatusTag = (status: string) => {
    const statusMap = {
      active: { color: 'green', text: '启用' },
      inactive: { color: 'red', text: '禁用' },
    };
    const config = statusMap[status] || { color: 'default', text: status };
    return <Tag color={config.color}>{config.text}</Tag>;
  };

  const getTypeTag = (type: 'node' | 'python' | 'bash') => {
    const typeMap = {
      node: { color: 'blue', text: 'Node.js' },
      python: { color: 'orange', text: 'Python' },
      bash: { color: 'green', text: 'Bash' },
    };
    return <Tag color={typeMap[type].color}>{typeMap[type].text}</Tag>;
  };

  const columns: ColumnsType<Script> = [
    {
      title: 'ID',
      dataIndex: 'id',
      key: 'id',
      width: 60,
    },
    {
      title: '脚本名称',
      dataIndex: 'name',
      key: 'name',
      width: 200,
      ellipsis: true,
    },
    {
      title: '描述',
      dataIndex: 'description',
      key: 'description',
      width: 250,
      ellipsis: true,
      render: (text) => text || '-',
    },
    {
      title: '类型',
      dataIndex: 'type',
      key: 'type',
      width: 80,
      render: getTypeTag,
    },
    {
      title: '状态',
      dataIndex: 'status',
      key: 'status',
      width: 80,
      render: getStatusTag,
    },
    {
      title: '更新时间',
      dataIndex: 'updatedAt',
      key: 'updatedAt',
      width: 150,
      render: (text) => new Date(text).toLocaleString(),
    },
    {
      title: '操作',
      key: 'action',
      width: 280,
      fixed: 'right',
      render: (_, record) => (
        <Space size="small">
          <Button
            size="small"
            icon={<EyeOutlined />}
            onClick={() => handleViewCode(record)}
          >
            查看
          </Button>
          <Button
            size="small"
            icon={<PlayCircleOutlined />}
            type="primary"
            onClick={() => handleExecute(record)}
            disabled={record.status !== 'active'}
          >
            执行
          </Button>
          <Button
            size="small"
            icon={<HistoryOutlined />}
            onClick={() => handleViewHistory(record)}
          >
            历史
          </Button>
          <Button
            size="small"
            icon={<EditOutlined />}
            onClick={() => handleEdit(record)}
          >
            编辑
          </Button>
          <Popconfirm
            title="确定要删除这个脚本吗？"
            onConfirm={() => handleDelete(record.id)}
          >
            <Button
              size="small"
              icon={<DeleteOutlined />}
              danger
            >
              删除
            </Button>
          </Popconfirm>
        </Space>
      ),
    },
  ];

  return (
    <div>
      <Card>
        <div style={{ marginBottom: 16 }}>
          <Space>
            <Button
              type="primary"
              icon={<PlusOutlined />}
              onClick={handleCreate}
            >
              新建脚本
            </Button>
            <Input.Search
              placeholder="搜索脚本名称"
              style={{ width: 200 }}
              onSearch={(value) => setFilters({ ...filters, name: value })}
              allowClear
            />
            <Select
              placeholder="选择类型"
              style={{ width: 120 }}
              allowClear
              onChange={(value) => setFilters({ ...filters, type: value })}
            >
              <Option value="node">Node.js</Option>
              <Option value="python">Python</Option>
              <Option value="bash">Bash</Option>
            </Select>
            <Select
              placeholder="选择状态"
              style={{ width: 120 }}
              allowClear
              onChange={(value) => setFilters({ ...filters, status: value })}
            >
              <Option value="active">启用</Option>
              <Option value="inactive">禁用</Option>
            </Select>
          </Space>
        </div>

        <Table
          columns={columns}
          dataSource={scripts}
          loading={loading}
          scroll={{ x: 1060 }}
          pagination={{
            current,
            pageSize,
            total,
            showSizeChanger: true,
            showQuickJumper: true,
            showTotal: (total) => `共 ${total} 条记录`,
            onChange: (page, size) => {
              setCurrent(page);
              setPageSize(size!);
            },
          }}
          rowKey="id"
        />
      </Card>

      {/* 编辑脚本模态框 */}
      <Modal
        title={currentScript ? '编辑脚本' : '新建脚本'}
        open={editModalVisible}
        onCancel={() => setEditModalVisible(false)}
        onOk={() => form.submit()}
        width={800}
        destroyOnClose
      >
        <Form
          form={form}
          layout="vertical"
          onFinish={handleSave}
        >
          <Form.Item
            name="name"
            label="脚本名称"
            rules={[
              { required: true, message: '请输入脚本名称' },
              { max: 100, message: '脚本名称不能超过100个字符' },
            ]}
          >
            <Input placeholder="请输入脚本名称" />
          </Form.Item>

          <Form.Item name="description" label="描述">
            <TextArea
              rows={2}
              placeholder="请输入脚本描述"
              maxLength={500}
              showCount
            />
          </Form.Item>

          <Form.Item
            name="type"
            label="脚本类型"
            rules={[{ required: true, message: '请选择脚本类型' }]}
          >
            <Select placeholder="请选择脚本类型">
              <Option value="node">Node.js</Option>
              <Option value="python">Python</Option>
              <Option value="bash">Bash</Option>
            </Select>
          </Form.Item>

          <Form.Item
            name="content"
            label="脚本内容"
            rules={[{ required: true, message: '请输入脚本内容' }]}
          >
            <TextArea
              rows={10}
              placeholder="请输入脚本内容"
              style={{ fontFamily: 'Monaco, Consolas, "Courier New", monospace' }}
            />
          </Form.Item>

          {currentScript && (
            <Form.Item name="status" label="状态">
              <Select>
                <Option value="active">启用</Option>
                <Option value="inactive">禁用</Option>
              </Select>
            </Form.Item>
          )}
        </Form>
      </Modal>

      {/* 代码查看器 */}
      <Drawer
        title={`查看脚本: ${currentScript?.name}`}
        placement="right"
        width={800}
        open={editorVisible}
        onClose={() => setEditorVisible(false)}
      >
        {currentScript && (
          <ScriptEditor
            script={currentScript}
            readOnly
          />
        )}
      </Drawer>

      {/* 执行结果抽屉 */}
      <Drawer
        title="执行结果"
        placement="right"
        width={800}
        open={executionDrawerVisible}
        onClose={() => setExecutionDrawerVisible(false)}
      >
        {currentExecution && (
          <ExecutionResult execution={currentExecution} />
        )}
      </Drawer>
    </div>
  );
};

export default Scripts;